/* 
Copyright DAUPHIN Maxime 2005

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
http://www.gnu.org/licenses/gpl.txt
*/
#ifndef __ANY_H__
#define __ANY_H__

#include "Gui.h"

namespace Gui {

class Any
{
	
public :
	Any(void) : m_content(NULL) {}

	template<typename ValueType>
	Any(const ValueType & value) 
		: m_content( new Holder<ValueType>(value) )
	{
	}

    Any(const Any & other)
      : m_content(other.m_content ? other.m_content->clone() : 0)
    {
    }
	~Any() { delete m_content; }

    template<typename ValueType>
    Any & operator=(const ValueType & rhs)
    {
        Any(rhs).swap(*this);
        return *this;
    }

    Any & operator=(const Any & rhs)
    {
        Any(rhs).swap(*this);
        return *this;
    }

    Any & swap(Any & rhs)
    {
        std::swap( m_content, rhs.m_content);
        return *this;
    }

	const std::type_info & type() const
	{
		return m_content ? m_content->type() : typeid(void);
	}

    class Placeholder
    {
    public:
        virtual ~Placeholder() {}
        virtual const std::type_info & type() const = 0;
		virtual Placeholder * clone() const = 0;
    };

	template<typename ValueType>
	class Holder : public Placeholder
	{
	public:
		Holder(const ValueType &value) : m_value(value) {};
		virtual const std::type_info & type() const
		{
			return typeid(ValueType);
		}
		virtual Placeholder * clone() const
		{
			return new Holder(m_value);
		}
		ValueType m_value;
	};

	Placeholder *m_content;

    template<typename ValueType>
    friend ValueType * any_cast(Any * operand)
    {
		if (  operand && operand->type() == typeid(ValueType) )
		{
			return &static_cast<Holder<ValueType> *>(operand->m_content)->m_value;
		}
        else
        {
			throw std::bad_cast();
			return NULL;
		}
    }

    template<typename ValueType>
    friend ValueType any_cast(Any & operand)
    {
		ValueType *result = any_cast<ValueType>(&operand);
		if ( result )
			return *result;
		throw 0;
	}
    
};

}; // End namespace Gui

#endif //#define __ANY_H__